package com.linxin.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linxin.reggie.common.CustomException;
import com.linxin.reggie.dto.DishDto;
import com.linxin.reggie.entity.Dish;
import com.linxin.reggie.entity.DishFlavor;
import com.linxin.reggie.mapper.DishFlavorMapper;
import com.linxin.reggie.mapper.DishMapper;
import com.linxin.reggie.service.DishFlavorService;
import com.linxin.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private DishFlavorService dishFlavorService;

    /**
     * 保存dish和dishFlavor
     *
     * @param dishDto
     */
    // @Transactional 操作多张表, 添加事务控制, 保证数据的一致性, 启动类需要添加@EnableTransactionManagement
    @Transactional
    @Override
    public void saveDishWithFlavor(DishDto dishDto) {
        // dishDto 中获取 dish 数据, 保存基本信息到菜品表中
        this.save(dishDto);

        // 获取菜品id
        Long id = dishDto.getId();

        // 获取菜品口味
        List<DishFlavor> flavors = dishDto.getFlavors();

        // stream流将id赋值给每一个口味
        flavors = flavors.stream().map((dishFlavor) -> {
            // 设置每个口味的id
            dishFlavor.setDishId(id);
            // 返回给每个dishFlavor
            return dishFlavor;
        }).collect(Collectors.toList());

        // 保存菜品口味到菜品口味表中
        // saveBatch 批量保存
        dishFlavorService.saveBatch(flavors);
    }

    @Override
    public DishDto getDishWithFlavor(Long id) {
        // 从dish表查询菜品的基本信息
        Dish dish = this.getById(id);

        // 将dish数据复制给dishDto对象
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish, dishDto);

        // 从口味表, 查询对应的菜品口味信息
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId, dish.getId());
        List<DishFlavor> list = dishFlavorService.list(dishFlavorLambdaQueryWrapper);

        // 将查询的口味集合赋值给dishDto的口味集合
        dishDto.setFlavors(list);

        // 返回dishDto
        return dishDto;
    }

    /**
     * 更新菜品信息
     *
     * @param dishDto
     */
    @Override
    @Transactional
    public void updateDishWithFlavor(DishDto dishDto) {
        // 更新dish表的基本信息
        // updateById可以直接传dishDto, dishDto继承了dish
        this.updateById(dishDto);

        // 根据id清除菜品口味表的对应的数据
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        // 使用等值查询
        queryWrapper.eq(DishFlavor::getDishId, dishDto.getId());
        // 删除对应的
        dishFlavorService.remove(queryWrapper);

        // 添加新的口味(先清除再添加)
        // 获取传入的口味
        List<DishFlavor> flavors = dishDto.getFlavors();
        // 为添加对应的菜品id
        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishDto.getId());
            return item;
        }).collect(Collectors.toList());

        // 保存到口味表
        dishFlavorService.saveBatch(flavors);
    }

    /**
     * 根据传入的id, 删除菜品信息(包括口味)
     *
     * @param ids
     */
    @Transactional
    @Override
    public void deleteDishWithFlavor(Long[] ids) {
        for (int i = 0; i < ids.length; i++) {
            // 菜品是否启售1, 停售0才能删除
            // 根据这个id获取菜品对象
            Dish dish = this.getById(ids[i]);
            if (dish.getStatus() == 1) {
                // 启售1, 不能删除
                // 抛出自定义异常
                throw new CustomException("选择的菜品中含有启售状态, 不能删除!!!");
            } else {
                // 停售0, 可以删除
                // 根据id删除dish表中的信息
                LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
                dishLambdaQueryWrapper.eq(Dish::getId, ids[i]);
                // 删除dish信息
                this.remove(dishLambdaQueryWrapper);

                // 根据id删除口味表的信息
                LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
                dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId, ids[i]);
                // 删除口味信息
                dishFlavorService.remove(dishFlavorLambdaQueryWrapper);
            }
        }
    }
}
